/*!
 * \file      utilities.h
 *
 * \brief     Helper functions implementation
 *
 * \copyright Revised BSD License, see section \ref LICENSE.
 *
 * \code
 *                ______                              _
 *               / _____)             _              | |
 *              ( (____  _____ ____ _| |_ _____  ____| |__
 *               \____ \| ___ |    (_   _) ___ |/ ___)  _ \
 *               _____) ) ____| | | || |_| ____( (___| | | |
 *              (______/|_____)_|_|_| \__)_____)\____)_| |_|
 *              (C)2013-2017 Semtech
 *
 * \endcode
 *
 * \author    Miguel Luis ( Semtech )
 *
 * \author    Gregory Cristian ( Semtech )
 */
#include <stdlib.h>
#include <stdio.h>
#include "utilities.h"
#include <string.h>

/*!
 * Redefinition of rand() and srand() standard C functions.
 * These functions are redefined in order to get the same behavior across
 * different compiler toolchains implementations.
 */
// Standard random functions redefinition start
#define RAND_LOCAL_MAX 2147483647L

static uint32_t next = 1;

int32_t rand1( void )
{
    return ( ( next = next * 1103515245L + 12345L ) % RAND_LOCAL_MAX );
}

void srand1( uint32_t seed )
{
    next = seed;
}
// Standard random functions redefinition end

int32_t randr( int32_t min, int32_t max )
{
    return ( int32_t )rand1( ) % ( max - min + 1 ) + min;
}

void memcpy1( uint8_t *dst, const uint8_t *src, uint16_t size )
{
    while( size-- )
    {
        *dst++ = *src++;
    }
}

void memcpyr( uint8_t *dst, const uint8_t *src, uint16_t size )
{
    dst = dst + ( size - 1 );
    while( size-- )
    {
        *dst-- = *src++;
    }
}

void memset1( uint8_t *dst, uint8_t value, uint16_t size )
{
    while( size-- )
    {
        *dst++ = value;
    }
}

int8_t Nibble2HexChar( uint8_t a )
{
    if( a < 10 )
    {
        return '0' + a;
    }
    else if( a < 16 )
    {
        return 'A' + ( a - 10 );
    }
    else
    {
        return '?';
    }
}


// 0x30 -> 0; a -> 0x0a; A -> 0x0a
uint8_t CharToHex(uint8_t ch)
{
    uint8_t val = (uint8_t)-1;

    if ((ch >= '0') && (ch <='9')) 
	{
        val = ch - '0';
    }
    else if ((ch >= 'A') && (ch <='F')) 
	{
        val = ch - 'A' + 10;
    }
    else if ((ch >= 'a') && (ch <='f')) 
	{
        val = ch - 'a' + 10;
    }
    return val;
}



void HexToString(char *des, uint8_t *src , uint16_t len)
{
    uint16_t i;
    uint8_t *p;
    char tmp[4];

    p = src;
    for(i=0; i<len; i++) 
	{
        memset1((void *)tmp, 0, sizeof(tmp));
        sprintf(tmp, "%02x", *p++);
        strcat(des, tmp);
    }
}


int StringToHex(uint8_t *pbDest, const char *pbSrc, uint16_t srcLen)
{
    uint16_t i=0,j=0;
    uint8_t chl,chh;

    memset1(pbDest, 0, srcLen/2);
    while (i < srcLen) 
	{
        if ((i+1) == srcLen) 
		{  
            chl = CharToHex(pbSrc[i]);
            pbDest[j] = chl<<4;
            j ++;
        }
		else
		{
            chh = CharToHex(pbSrc[i]);
            chl = CharToHex(pbSrc[i+1]);
            pbDest[j] = (chh << 4) | chl;
            j ++;
        }
        i = i+2;
    }
    return j;
}



